<?php
namespace App\Admin\Controllers\SalesReport;

use App\Models\Basics\SysPlatAccount;
use App\Models\Basics\SysArea;
use App\Models\SalesReport\FBADeposit;
use Encore\Admin\Controllers\AdminController;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Request;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Illuminate\Pagination\Paginator;
class DepositController extends AdminController{

    protected $title = '亚马逊转款报表';

    protected $filters = [
        'start_date' => null,
        'end_date' => null,
        'settlement_id' => null,
        'account_id' => null,
        'area_id' => null,
        'country_id' => null,
        'status' => null,
    ];

    protected function grid()
    {
        $filtersField = array_keys($this->filters);
        $filters = $this->_getFilters($filtersField);
        $this->_initFilters($filters);
        $status = $filters['status'];
        $query = $this->_initQuery($filters);
        $headers = FBADeposit::headersField();
        if($status){
            $data = $this->_paginatorCustomize($query,$headers);
            $paginator = $data['paginator'];
            $total = $data['sum'];
        }else{
            $_query = clone $query;
            $paginator = $this->_paginator($query);
            $total = $this->_sum($_query,$headers);
        }
        $action = getAction($filtersField);
        $filtersBlade = [];
        $filtersBlade['account_id'] = getOptions(SysPlatAccount::options(),$this->filters['account_id']);
        $filtersBlade['area_id'] = getOptions(SysArea::options(),$this->filters['area_id']);
        $filtersBlade['country_id'] = getOptions(FBADeposit::countryOptions(),$this->filters['country_id']);
        $filtersBlade['start_date'] = $this->filters['start_date'];
        $filtersBlade['end_date'] = $this->filters['end_date'];
        $filtersBlade['settlement_id'] = $this->filters['settlement_id'];
        $filtersBlade['status'] = getOptions(FBADeposit::$_statusOption,$this->filters['status']);
        $downloadUrl = '/xqc/sales-report/fba-deposit-download?' . http_build_query(array_merge(Request::all(),['_export_' => true]));
        return view('sales-report.fba-deposit.index', compact('paginator','total','headers','filtersBlade','action','downloadUrl'));
    }

    private function _getFilters($filtersField){
        $filters = [];
        foreach ($filtersField as $field){
            $filters[$field] = request($field);
        }
        return $filters;
    }

    private function _initFilters($filters){
        foreach ($filters as $field => $filter){
            $this->filters[$field] = $filter;
        }
    }

    private function _initQuery($filters){
        $query = FBADeposit::query()->orderBy('settlement_id','DESC');
        foreach ($filters as $field => $filter){
            if(!$filter)continue;
            if($field == 'start_date'){
                $query->where('deposit_date','>=',$filter .' 00:00:00');
            }
            if($field == 'end_date'){
                $query->where('deposit_date','<=',$filter .' 23:59:59');
            }
            if(in_array($field,['account_id','area_id','country_id','status','settlement_id'])){
                $query->where($field,$filter);
            }
        }
        return $query;
    }

    private function _setPageCustomize($data){
        $perPage = (int) (request("per_page",10));
        if(request()->has("page")){
            $page = (int) (request("page"));
            $page = $page <= 0 ? 1 : $page;
        }else{
            $page = 1;
        }
        $total = count($data);
        $items = array_slice($data,($page - 1) * $perPage,$perPage);
        return new LengthAwarePaginator($items,$total,$perPage,$page,[
            'path' => Paginator::resolveCurrentPath(),
            'pageName' => 'page',
        ]);
    }

    private function _paginatorCustomize($query,$headers){
        $res = $query->where('cur_reserve_amount','<',0)->get();
        $data = [];
        foreach ($res as $re){
            $key = $re->account_id.'_'.$re->country_id;
            if(!array_key_exists($key,$data)){
                $data[$key] = $re;
            }else{
                $reTemp = $data[$key];
                if(strtotime($reTemp->deposit_date) < strtotime($re->deposit_date)){
                    $data[$key] = $re;
                }
            }
        }
        $sum = collect();
        foreach ($headers as $field => $item){
            if($item['sumField']){
                $sum->{$field} = 0;
            }else{
                continue;
            }
        }
        foreach ($data as $_data){
            foreach ($headers as $field => $item){
                if($item['sumField']){
                    $sum->{$field} += $_data->rate_odds * $_data->{str_replace('_rmb','',$field)};
                }else{
                    continue;
                }
            }
        }
        return ['paginator' => $this->_setPageCustomize($data)->appends(Request::input()),'sum' => $sum];
    }

    private function _paginator($query){
        return $query->paginate((int) (request("per_page",10)))->appends(Request::input());
    }

    private function _sum($query,$headers){
        $sum = $query->selectRaw($this->__getSumFields($headers))->groupBy(1)->first();
        return $sum ?: $this->__getSumFieldsInit($headers);
    }

    private function __getSumFields($headers){
        $re = '';
        foreach ($headers as $field => $item){
            if($item['sumField']){
                $re .= 'sum(rate_odds * '.str_replace('_rmb','',$field).') as '.$field.',';
            }else{
                continue;
            }
        }
        return $re.'1';
    }

    private function __getSumFieldsInit($headers){
        $re = collect();
        foreach ($headers as $field => $item){
            if($item['sumField']){
                $re->{$field} = 0;
            }else{
                continue;
            }
        }
        return $re;
    }

    public function download(){
        $filtersField = array_keys($this->filters);
        $filters = $this->_getFilters($filtersField);
        $query = $this->_initQuery($filters);
        $status = $filters['status'];
        if($status){
            $d_res = $query->get();
            $data = [];
            foreach ($d_res as $d_re){
                $key = $d_re->account_id.'_'.$d_re->country_id;
                if(!array_key_exists($key,$data)){
                    $data[$key] = $d_re;
                }else{
                    $reTemp = $data[$key];
                    if(strtotime($reTemp->deposit_date) < strtotime($d_re->deposit_date)){
                        $data[$key] = $d_re;
                    }
                }
            }
            $this->_exe2Download($data);
        }else{
            $this->_exeDownload($query);
        }
    }

    private function _exe2Download($downloadData){
        $head = Arr::pluck(FBADeposit::headersField(),'title');
        set_time_limit(0);
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="亚马逊转款报表.csv"',
        ]);
        $response->setCallback(function () use ($head, $downloadData) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $i = 0;
            $num = 100;
            while (true){
                if(empty($downloadData))break;
                $re = array_splice($downloadData,$i,$num);
                $data = FBADeposit::getDownloadData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            }
            fclose($fp);
        });
        $response->send();
        exit(0);
    }

    private function _exeDownload($query){
        $head = Arr::pluck(FBADeposit::headersField(),'title');
        set_time_limit(0);
        $response = new StreamedResponse(null, 200, [
            'Content-Type'        => 'text/csv;charset=utf-8',
            'Content-Disposition' => 'attachment;filename="亚马逊转款报表.csv"',
        ]);
        $response->setCallback(function () use ($head, $query) {
            $fp = fopen('php://output', 'w');
            fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
            fputcsv($fp, $head);
            $query->chunk(200, function ($re) use ($fp){
                $data = FBADeposit::getDownloadData($re);
                foreach ($data as $item) {
                    fputcsv($fp, $item);
                }
            });
            fclose($fp);
        });
        $response->send();
        exit(0);
    }
}
